import requests
import base64
import cv2
from PyQt5.QtWidgets import QMainWindow, QFileDialog, QMessageBox, QInputDialog
from PyQt5.QtChart import QChartView, QChart, QPieSeries
from PyQt5.QtCore import QTimer, QDateTime, pyqtSignal
from PyQt5.QtGui import QColor, QPixmap
from MainWindow import Ui_MainWindow
from camera import camera
from detectThread import detectThread
from adduserWindow import adduserWindow
from deluserWindow import deluserWindow
from signWindow import signWindow
import sqlite3


'''
子类 myWindow 继承 UI_MainWindow 和 QMainWindow
Ui_MainWindow:
    包含界面的设计，窗口的窗口部件
QMainWindow:
    包含整个界面窗口，窗口操作
myWindow:
    完整的窗口
'''
class myWindow(Ui_MainWindow, QMainWindow):
    # 自定义信号与槽
    detect_data_signal = pyqtSignal(bytes)
    def __init__(self):  # 对象的初始化方法
        super(myWindow, self).__init__()  # 通过super()来调用父类的__init__()函数
        self.setupUi(self)  # 创建界面内容
        self.camera_status = False
        self.label.setScaledContents(True)
        self.label.setPixmap(QPixmap("./pic/614743"))
        # 初始时，摄像头未打开
        self.camera_status = False
        # 信号与槽的关联
        # 指定对象：self.actionopen、信号：triggered、关联(槽函数)：connect(self.on_actionopen)
        self.actionopen.triggered.connect(self.on_actionopen)   # 关联启动签到
        self.actionclose.triggered.connect(self.on_actionclose) # 关联关闭签到
        self.actionstatus.triggered.connect(self.get_signinfo) # 获取签到信息
        # 添加用户组
        self.actionaddgroup.triggered.connect(self.add_group)
        # 删除用户组
        self.actiondelgroup.triggered.connect(self.del_group)
        # 查询组类信息
        self.actionquerylist.triggered.connect(self.show_grouplist)
        # 关联添加用户
        self.actionadduser.triggered.connect(self.adduser)
        # 关联删除用户
        self.actiondeluser.triggered.connect(self.deluser)

        # 创建定时器对象，用于实时显示时间
        self.datetime = QTimer()
        # 每500ms获取一次系统时间
        self.datetime.start(500)
        self.datetime.timeout.connect(self.get_datetime)

        # 获取百度人脸检测accesstoken值
        self.get_accesstoken()

        # 创建一张签到表
        # create_signIn_table = "CREATE TABLE SIGNIN(user_id  TEXT, group_id TEXT, name TEXT,time TEXT,PRIMARY KEY(user_id, group_id))"
        # cursor.execute(create_signIn_table)
        # 连接数据库
        db = sqlite3.connect('database.db')
        # 获取数据库游标
        cursor = db.cursor()
        # 每次重新运行程序时，需将上一次的签到数据清除
        delete_sql = "delete from SIGNIN"
        cursor.execute(delete_sql)
        # 提交到数据库
        db.commit()
        # 关闭数据库
        db.close()

        # 记录签到人数
        self.count = 0
        # 滚动条
        self.progressBar.setValue(0)


    # 获取日期，并添加到界面中
    def get_datetime(self):
        qdatetime = QDateTime.currentDateTime()
        self.label_2.setText(qdatetime.toString("ddd    yyyy/MM/dd    hh:mm:ss"))


    def on_actionclose(self):
        if self.camera_status == False:
            QMessageBox.warning(self, "warning", "签到未启动，无法关闭！")
            return
        # 关闭定时器
        self.timeshow.stop()
        self.detection_time.stop()
        # 关闭线程
        self.detect_thread.flag = False
        self.detect_thread.quit()
        self.detect_thread.wait()
        # 断开连接
        self.timeshow.timeout.disconnect(self.show_camera)
        self.detection_time.timeout.disconnect(self.get_cameradata)
        self.detect_thread.transmit_data.disconnect(self.get_detectdata)
        self.detect_thread.search_data.disconnect(self.get_searchdata)
        self.detect_data_signal.disconnect(self.detect_thread.get_base64)
        # 关闭摄像头
        self.camera_data.camera_close()
        self.camera_status = False
        # 画面设置为初始状态
        self.label.setPixmap(QPixmap("./pic/614743"))
        self.plainTextEdit.clear()
        self.plainTextEdit_2.clear()



    def on_actionopen(self):
        # 启动摄像头
        self.camera_data = camera()
        self.camera_status = True
        # 启动定时器，进行定时,每个多长时间获取摄像头信号进行显示
        self.timeshow = QTimer(self)
        self.timeshow.start(50)
        # 每隔50毫秒将产生一个信号timeout
        self.timeshow.timeout.connect(self.show_camera)

        # 每4000ms调用一次人脸检测
        # 创建检测线程
        self.create_thread()

        # 获取要检测的数据
        self.detection_time = QTimer(self)
        self.detection_time.start(5000)
        self.detection_time.timeout.connect(self.get_cameradata)

        self.detect_thread.transmit_data.connect(self.get_detectdata)
        self.detect_thread.search_data.connect(self.get_searchdata)
        self.detect_thread.sign_success.connect(self.update_sign)


    # 更新签到率
    def update_sign(self, data):
        self.get_total()
        if data == "True":
            self.count += 1
            self.progressBar.setValue(round((self.count/self.total_number)*100))



    def get_cameradata(self):
        # 摄像头获取画面
        camera_img = self.camera_data.read_camera()
        # 把摄像头画面转换成图片
        _, enc = cv2.imencode('.jpg', camera_img)
        # 设置为base64编码格式
        base64_image = base64.b64encode(enc.tobytes())
        # 产生信号，传递数据
        self.detect_data_signal.emit(bytes(base64_image))



    # 创建一个线程
    def create_thread(self):
        list = self.query_list()
        group_list = list['result']['group_id_list']
        self.detect_thread = detectThread(self.access_token, group_list)
        self.detect_thread.start()
        self.detect_data_signal.connect(self.detect_thread.get_base64)


    def show_camera(self):
        # 获取摄像头转换数据
        img = self.camera_data.camera_toPic()
        # 显示画面
        self.label.setPixmap(img)


    def get_accesstoken(self):
        # client_id 为官网获取的AK， client_secret 为官网获取的SK
        host = 'https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=【官网获取的AK】&client_secret=【官网获取的SK】'
        # 发送网路请求
        response = requests.get(host)
        if response:
            data = response.json()
            self.access_token = data.get('access_token')


    def get_searchdata(self, data):
        self.plainTextEdit_2.clear()
        self.plainTextEdit_2.appendPlainText(data)



    # 槽函数，获取检测数据
    def get_detectdata(self, data):
        self.plainTextEdit.clear()
        if data['error_code'] != 0:
            self.plainTextEdit.appendPlainText("no face!!!")
            return
        if data['error_msg'] == 'SUCCESS':
            # 人脸数目
            face_num = data['result']['face_num']
            # if face_num == 0:
            #     self.plainTextEdit.appendPlainText("no face!!!")
            #     return
            # 人脸信息：data['result']['face_list']
            for i in range(face_num):
                age = data['result']['face_list'][i]['age']
                # beauty = data['result']['face_list'][i]['beauty']
                gender = data['result']['face_list'][i]['gender']['type']
                glasses = data['result']['face_list'][i]['glasses']['type']
                face_type = data['result']['face_list'][i]['face_type']['type']
                # 在窗口中显示信息
                self.plainTextEdit.appendPlainText("年龄: "+str(age))
                # self.plainTextEdit.appendPlainText("颜值分数: "+str(beauty))
                self.plainTextEdit.appendPlainText("性别: "+str(gender))
                if glasses == 'none':
                    glasses = '否'
                else:
                    glasses = '是'
                self.plainTextEdit.appendPlainText("是否佩戴眼镜: "+str(glasses))
                self.plainTextEdit.appendPlainText("人脸类别: "+str(face_type))


    def add_group(self):
        # 创建输入对话框
        group, ret = QInputDialog.getText(self, "添加用户组", "输入id(由数字、字母、下划线组成)")
        if group == "":
            return
        request_url = "https://aip.baidubce.com/rest/2.0/face/v3/faceset/group/add"
        params = {
            "group_id": group
        }
        access_token = self.access_token
        request_url = request_url + "?access_token=" + access_token
        headers = {'content-type': 'application/json'}
        response = requests.post(request_url, data=params, headers=headers)
        if response:
            message = response.json()
            if message['error_code'] == 0:
                QMessageBox.information(self, "addgroup", "添加成功！")
            else:
                QMessageBox.warning(self, "addgroup", "添加失败！")


    def del_group(self):
        request_url = "https://aip.baidubce.com/rest/2.0/face/v3/faceset/group/delete"
        list = self.query_list()
        group, ret = QInputDialog.getText(self, "删除用户组", "用户组: " + str(list['result']['group_id_list']))
        if group == "":
            return
        params = {
            "group_id": group
        }
        access_token = self.access_token
        request_url = request_url + "?access_token=" + access_token
        headers = {'content-type': 'application/json'}
        response = requests.post(request_url, data=params, headers=headers)
        if response:
            message = response.json()
            if message['error_code'] == 0:
                QMessageBox.information(self, "DelGroup", "删除成功！")
            else:
                QMessageBox.warning(self, "DelGroup", "删除失败！")


    # 获取用户组列表
    def query_list(self):
        request_url = "https://aip.baidubce.com/rest/2.0/face/v3/faceset/group/getlist"

        params = {
            "start": 0,
            "length": 100
        }
        access_token = self.access_token
        request_url = request_url + "?access_token=" + access_token
        headers = {'content-type': 'application/json'}
        response = requests.post(request_url, data=params, headers=headers)
        if response:
            return response.json()


    def show_grouplist(self):
        list = self.query_list()
        string = '用户组列表\n'
        for i in list['result']['group_id_list']:
            string += i + '\n'
        QMessageBox.information(self, "GroupList", string)


    def adduser(self):
        if self.camera_status:
            QMessageBox.warning(self, "cameraStatus", "摄像头已经被打开, 请先关闭再添加！")
            return
        request_url = "https://aip.baidubce.com/rest/2.0/face/v3/faceset/user/add"
        list = self.query_list()
        # 创建一个窗口填写内容
        window = adduserWindow(list['result']['group_id_list'], self)
        window_status = window.exec_()
        if window_status != 1:
            return
        params = {
            "image": window.base64_image,
            "image_type": "BASE64",
            "group_id": window.group_id,
            "user_id": window.user_id,
            "user_info": "姓名: " + window.user_name
        }
        access_token = self.access_token
        request_url = request_url + "?access_token=" + access_token
        headers = {'content-type': 'application/json'}
        response = requests.post(request_url, data=params, headers=headers)
        if response:
            message = response.json()
            if message['error_code'] == 0:
                QMessageBox.information(self, "AddUser", "用户添加成功！")
            else:
                QMessageBox.critical(self, "AddUser", "用户添加失败！")


    def deluser(self):
        group_list = self.query_list()
        window = deluserWindow(self.access_token, group_list['result']['group_id_list'], self)
        window_status = window.exec_()
        if window_status:
            QMessageBox.information(self, "DelUser", "用户删除成功！")


    # 获取user_id列表
    def user_list(self, group_id):
        request_url = "https://aip.baidubce.com/rest/2.0/face/v3/faceset/group/getusers"

        params = {
            "group_id": group_id
        }
        access_token = self.access_token
        request_url = request_url + "?access_token=" + access_token
        headers = {'content-type': 'application/json'}
        response = requests.post(request_url, data=params, headers=headers)
        if response:
            message = response.json()
            if message['error_code'] == 0:
                return message['result']['user_id_list']
            else:
                return []

    # 获取总人数
    def get_total(self):
        self.total_number = 0
        list = self.query_list()
        group_list = list['result']['group_id_list']
        for x in group_list:
            user_list = self.user_list(x)
            for j in user_list:
                self.total_number += 1



    def get_signinfo(self):
        if self.camera_status:
            QMessageBox.information(self, "cameraStatus", "正在签到中！")
            return
        list = self.query_list()
        group_list = list['result']['group_id_list']
        data_list = []
        for x in group_list:
            user_list = self.user_list(x)
            for j in user_list:
                a = j + '-' + x
                data_list.append(a)
        window = signWindow(self.access_token, data_list)
        window.exec_()
        window.cursor.close()
        window.db.close()





